import CONST from '@/const/const'

const REG_EXP = {
  // 整数、小树位数校验包含0的金额 NUMBER[16,4]
  NUMBER: (param, value, msg) => {
    if (isNaN(value)) {
      return CONST.NUMBER_TIP
    }
    if (param) {
      const numDigit = param[0] - param[1] - 1
      const tailDigit = param[1]
      const regExp = '^[-,+]?((([1-9][\\d]{0,' + numDigit + '})(\\.[\\d]{1,' + tailDigit + '})?)|(0(\\.[\\d]{0,' + tailDigit + '})))$'
      if (!new RegExp(regExp).test(value)) {
        msg = msg || `最多输入${numDigit + 1}位整数，${tailDigit}位小数`
        return msg
      }
    }
  },
  // 范围校验 RANGE_NUMBER["",5] 即录入数字<=5 RANGE_NUMBER[1,5] 即录入数字>=1 && <=5
  RANGE_NUMBER: function(param, value, msg) {
    const min = param[0]
    const max = param[1]
    if (isNaN(value)) {
      return CONST.NUMBER_TIP
    }
    if (!this.isNull(min)) {
      if (value < min) {
        return msg || `请输入大于${min}的数字`
      }
    }
    if (!this.isNull(max)) {
      if (value > max) {
        return msg || `请输入小于${max}的数字`
      }
    }
  },
  NG_INT: function(param, value, msg) {
    const regExp = /^(-[1-9][0-9]*|0)$/
    msg = msg || '请输入0或负整数'
    if (!regExp.test(value)) {
      return msg
    }
  },
  YJ_INT: function(param, value, msg) {
    const regExp = /^(0|[1-9][0-9]*|-[1-9][0-9]*)$/
    msg = msg || '请输入-100(包含)以上的整数'
    if (!regExp.test(value) || value * 1 < -100) {
      return msg
    }
  },
  // 校验正整数
  P_INT: function(param, value, msg) {
    const regExp = /^\+?[1-9][0-9]*$/
    msg = msg || '请输入正整数'
    if (!regExp.test(value)) {
      return msg
    }
  },
  // 校验温度
  TEMP: function(param, value, msg) {
    const regExp = /^(?:0|[1-9][0-9]?|100)$/
    msg = msg || '请输入0-100'
    if (!regExp.test(value)) {
      return msg
    }
  },
  // 校验整数
  INT: function(param, value, msg) {
    const regExp = /^[0-9]*$/
    msg = msg || '请输入包含0的正整数'
    if (!regExp.test(value)) {
      return msg
    }
  },
  // 校验最多n位的正整数
  MAXINT: function(param, value, msg) {
    const regExp = /^[0-9]*$/
    const max = param[0]
    msg = msg || '请输入最多' + max + '位的正整数'
    if (!regExp.test(value) || value.length > max || value == 0) {
      return msg
    }
  },
  // 校验字符串最多多少位
  STR_RANGE: function(param, value, msg) {
    const [min, max] = param
    const len = value.length
    if (!max && len > min) {
      return msg || `最大长度为${min}位`
    }
    if (min && max && (len > max || len < min)) {
      return msg || `长度只能在${min}-${max}位之间`
    }
  },
  // 校验整数、小数位数 decLength[2] 整数最多2位 decLength[5,2]整数最多5位，小数2位
  DEC_LENGTH: function(param, value, msg) {
    const [min, max] = param
    const regExp = `^-?([0-9])+(\\.[0-9]{1,${max}})?$`
    if (!new RegExp(regExp).test(value)) {
      return msg || `小数最多${max}位`
    } else if (value.split('.')[0].length > min) {
      return msg || `整数最多${min}位`
    }
  },
  // 校验日期范围，开始日期不能大于结束日期，开始日期与结束日期之间的天数不能大于?天，如果没有设置天数，则不做日期天数的判断
  DATE_RANGE: function(param, value, msg) {
    if (!Array.isArray(value) || value.length !== 2) {
      return
    }
    let startDate = value[0]
    let endDate = value[1]
    if (typeof value[0] === 'string') {
      const str1 = value[0].substr(0, 4) + '/' + value[0].substr(4, 2) + '/' + value[0].substr(6, 2)
      const str2 = value[1].substr(0, 4) + '/' + value[1].substr(4, 2) + '/' + value[1].substr(6, 2)
      startDate = new Date(str1)
      endDate = new Date(str2)
    }
    if (startDate.getTime() > endDate.getTime()) {
      return '开始日期不能大于结束日期!'
    }
    if (Array.isArray(param) && param.length > 0) {
      const days = param[0] // 天数
      const oneday = 24 * 60 * 60 * 1000
      const diff = (endDate.getTime() - startDate.getTime()) / oneday
      if (diff > days) {
        return `所选日期不能超过${days}天`
      }
    }
  },
  // 手机号
  MOBILE: function(param, value, msg) {
    const regExp = /^((1[0-9]{1}))+\d{9}$/
    msg = msg || '手机号码不正确'
    if (!regExp.test(value)) {
      return msg
    }
  },
  // 邮箱
  EMAIL: function(param, value, msg) {
    const regExp = /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/
    msg = msg || '邮箱不正确'
    if (!regExp.test(value)) {
      return msg
    }
  },
  // 身份证
  IDCARD: function(param, value, msg) {
    const regExp = /^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/
    msg = msg || '身份证号码不正确'
    if (!regExp.test(value)) {
      return msg
    }
  },
  // vin前八位
  VINQBW: function(param, value, msg) {
    const regExp = /^[0-9A-HJ-NPR-Z]{8}$/
    msg = msg || '8位的大写字母与数字的组合 并且大写字母不能为"O","I","Q"'
    if (!regExp.test(value)) {
      return msg
    }
  },
  // vin号
  VIN: function(param, value, msg) {
    const regExp = /^[0-9A-HJ-NPR-Z]{17}$/
    msg = msg || '17位的大写字母与数字的组合 并且大写字母不能为"O","I","Q"'
    if (!regExp.test(value)) {
      return msg
    }
  },
  // 安装零件序列号
  SCAN_TRACK_NO: function(param, value, msg) {
    const regExp = /^[0-9A-HJ-NPR-Z]{17}$/
    msg = msg || '17位的大写字母与数字的组合 并且大写字母不能为"O","I","Q"'
    if (!regExp.test(value)) {
      return msg
    }
  },
  // 分类编码(缺陷分类维护)
  CLASSIFY_ISSUE_CODE: function(param, value, msg) {
    const regExp = /^(?![0-9]+$)(?![A-Z]+$)[0-9A-Z]{2}$/
    msg = msg || '填写2位长度，必须为数字和大写字母的组合!'
    if (!regExp.test(value)) {
      return msg
    }
  },
  // 缺陷编码(标准缺陷维护)
  ISSUE_CODE: function(param, value, msg) {
    const regExp = /^(?![0-9]+$)(?![A-Z]+$)[A-Z][0-9A-Z]{3}$/
    msg = msg || '填写4位长度，必须为数字和大写字母的组合，且第一位必须为大写字母!'
    if (!regExp.test(value)) {
      return msg
    }
  },
  // 部位编码(车辆部位维护)
  CAR_AREA_CODE: function(param, value, msg) {
    const regExp = /^(?![0-9]+$)(?![A-Z]+$)[0-9A-Z]{2}$/
    msg = msg || '填写2位长度，必须为数字和大写字母的组合!'
    if (!regExp.test(value)) {
      return msg
    }
  },
  // 部件编码(车辆部件维护)
  CAR_MODULES_CODE: function(param, value, msg) {
    const regExp = /^(?![0-9]+$)(?![A-Z]+$)[0-9A-Z]{3}$/
    msg = msg || '填写3位长度，必须为数字和大写字母的组合!'
    if (!regExp.test(value)) {
      return msg
    }
  }
}

const validator = function({ rule, value, callback, msg = [], required = true, type = [] } = {}) {
  const isNullValue = this.isNull(value)
  if (required && isNullValue) {
    callback(CONST.NULL_TIP)
    return
  } else {
    const errors = []
    !isNullValue && type.forEach((item, index) => {
      let regParam
      if (item.includes('[')) {
        regParam = item.substring(item.lastIndexOf('['))
        item = item.replace(regParam, '')
      }
      let error
      const tipMsg = msg[index]
      if (regParam) {
        regParam = JSON.parse(regParam)
        error = REG_EXP[item].call(this, regParam, value, tipMsg)
      } else {
        error = REG_EXP[item].call(this, regParam, value, tipMsg)
      }
      if (typeof error === 'string') {
        errors.push(error)
      }
    })
    if (errors.length) {
      callback(errors)
    } else {
      callback()
    }
  }
}
/**
 * 规则校验
 * @param { Array } msg 报错提示信息 ['报错', '小数位数2']
 * @param { Boolean } required 是否必填。默认必填
 * @param { Array } type 正则类型 ['A', 'B[16,2]'] 对应上面REG_EXP规则
 */
const hey_validator = function({ msg = [], required = true, type = [], trigger = ['change', 'blur'] } = {}) {
  const vm = this
  return [{
    required,
    trigger,
    validator: (rule, value, callback) => {
      validator.call(vm, {
        rule, value, callback, msg,
        required: rule ? rule.required : required,
        type
      })
    }
  }]
}

export default hey_validator
